package com.ihrm.common.interceptor;

import com.ihrm.common.entity.ResultCode;
import com.ihrm.common.exception.CommonException;
import com.ihrm.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器
 *
 * HandlerInterceptor:
 *   preHandle()：在进入到controller业务处理器处理请求之前执行被调用的内容
 *     boolean:
 *       true: 继续执行下一个拦截器，或者controller业务处理器
 *       false: 拦截请求，不继续执行下一个拦截器，也不执行controller业务处理器
 *   postHandle()：在controller业务处理器处理请求之后执行被调用的内容
 *   afterCompletion()：在controller业务处理器处理请求之后执行被调用的内容，
 *     且在preHandle()方法返回true时，响应结束之前执行的内容
 * 1.简化获取token数据的代码编写
 *   统一的用户校验(是否登录)
 * 2.判断用户是否具有当前访问接口的权限
 */
@Component
public class JwtInterceptor implements HandlerInterceptor {

	@Autowired
	private JwtUtil jwtUtils;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		/**
		 * 通过拦截器获取token数据，简化获取token数据的代码编写(判断是否登录)
		 * 1.通过request获取请求token信息
		 * 2.解析获取claims
		 * 3.将claims绑定到request域中
		 */
/*		String requestURI = request.getRequestURI();
		System.out.println("拦截器处理请求: " + requestURI);

		// 检查是否应该排除
		if (requestURI.endsWith("/sys/login")) {
			System.out.println("登录请求，放行");
			return true;
		}*/

		//1.通过request获取请求token信息
		String authorization = request.getHeader("Authorization");
		//判断Authorization是否为空或者Bearer开头
		if(!StringUtils.isEmpty(authorization) && authorization.startsWith("Bearer")){
			//获取token数据
			String token = authorization.replace("Bearer ", "");
			Claims claims = jwtUtils.parseJwt(token);
			if(claims!=null){
				//通过claims获取当前用户可访问的Api权限字符串
				String apis = (String)claims.get("apis");//api-user-delete
				//通过handler获取接口上的requestMapping注解
				HandlerMethod h=(HandlerMethod) handler;
				RequestMapping methodAnnotation = h.getMethodAnnotation(RequestMapping.class);
				//获取当前请求中的name属性
				String name =methodAnnotation.name();
				//判断当前用户是否具有访问当前接口的权限
				if(apis.contains(name)){
					//将claims绑定到request域中
					request.setAttribute("user_claims",claims);
					return true;
				}else{
					throw new CommonException(ResultCode.UNAUTHORISE);
				}

			}
		}
		throw new CommonException(ResultCode.UNAUTHENTICATED);
	}
}

